<!DOCTYPE HTML>
<html>

<head>
	<link rel="bookmark"  type="image/x-icon"  href="/img/logo_miccall.png"/>
	<link rel="shortcut icon" href="/img/logo_miccall.png">
	
			    <title>
    Ame雨
    </title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
    <link rel="stylesheet" href="/amelin-ting/css/mic_main.css" />
    <link rel="stylesheet" href="/amelin-ting/css/dropdownMenu.css" />
    <meta name="keywords" content="Ame雨" />
    
    	<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
	 
    <noscript>
        <link rel="stylesheet" href="/amelin-ting/css/noscript.css" />
    </noscript>
    <style type="text/css">
        body:before {
          content: ' ';
          position: fixed;
          top: 0;
          background: url('/amelin-ting/img/bg.jpg') center 0 no-repeat;
          right: 0;
          bottom: 0;
          left: 0;
          background-size: cover; 
        }
    </style>

			    
  
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script async type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
  


    <script src="/amelin-ting/js/jquery.min.js"></script>
    <script src="/amelin-ting/js/jquery.scrollex.min.js"></script>
    <script src="/amelin-ting/js/jquery.scrolly.min.js"></script>
    <script src="/amelin-ting/js/skel.min.js"></script>
    <script src="/amelin-ting/js/util.js"></script>
    <script src="/amelin-ting/js/main.js"></script>
	
<meta name="generator" content="Hexo 5.4.0"></head>
    
		
<!-- Layouts -->



<!--  代码渲染  -->
<link rel="stylesheet" href="/css/prism_coy.css" />
<link rel="stylesheet" href="/css/typo.css" />
<!-- 文章页 -->
<body class="is-loading">
    <!-- Wrapper 外包 s-->
    <div id="wrapper" class="fade-in">
        <!-- Intro 头部显示 s -->
        <!-- Intro 头部显示 e -->
        <!-- Header 头部logo start -->
        <header id="header">
    <a href="/amelin-ting/" class="logo">Art Space</a>
</header>
        <!-- Nav 导航条 start -->
        <nav id="nav" class="special" >
            <ul class="menu links" >
			<!-- Homepage  主页  --> 
			<li >
	            <a href="/amelin-ting/" rel="nofollow">主页</a>
	        </li>
			<!-- categories_name  分类   --> 
	        
	        <li class="active">
	            <a href="#s1">分类</a>
	                    <ul class="submenu">
	                        <li>
	                        <a class="category-link" href="/amelin-ting/categories/Go/">Go</a></li><li><a class="category-link" href="/amelin-ting/categories/django/">django</a></li><li><a class="category-link" href="/amelin-ting/categories/drf/">drf</a></li><li><a class="category-link" href="/amelin-ting/categories/gin/">gin</a></li><li><a class="category-link" href="/amelin-ting/categories/go/">go</a></li><li><a class="category-link" href="/amelin-ting/categories/linux/">linux</a></li><li><a class="category-link" href="/amelin-ting/categories/mysql/">mysql</a></li><li><a class="category-link" href="/amelin-ting/categories/python/">python</a></li><li><a class="category-link" href="/amelin-ting/categories/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/">内网穿透</a></li><li><a class="category-link" href="/amelin-ting/categories/%E5%89%8D%E7%AB%AF/">前端</a>
	                    </ul>
	        </li>
	        
	        <!-- archives  归档   --> 
	        
	        
		        <!-- Pages 自定义   -->
		        
		        <li>
		            <a href="/about/" title="简历">
		                简历
		            </a>
		        </li>
		        
		        <li>
		            <a href="/group/" title="团队">
		                团队
		            </a>
		        </li>
		        
		        <li>
		            <a href="/gallery/" title="图库">
		                图库
		            </a>
		        </li>
		        
		        <li>
		            <a href="/tag/" title="标签">
		                标签
		            </a>
		        </li>
		        


            </ul>
            <!-- icons 图标   -->
			<ul class="icons">
                    
                    <li>
                        <a title="github" href="https://github.com/miccall" target="_blank" rel="noopener">
                            <i class="icon fa fa-github"></i>
                        </a>
                    </li>
                    
                    <li>
                        <a title="500px" href="http://500px.com" target="_blank" rel="noopener">
                            <i class="icon fa fa-500px"></i>
                        </a>
                    </li>
                    
			</ul>
</nav>

        <div id="main" >
            <div class ="post_page_title_img" style="height: 25rem;background-image: url(https://img1.baidu.com/it/u=2936761779,3211079715&amp;fm=26&amp;fmt=auto);background-position: center; background-repeat:no-repeat; background-size:cover;-moz-background-size:cover;overflow:hidden;" >
                <a href="#" style="padding: 4rem 4rem 2rem 4rem ;"><h2 >Go日志库--Zap</h2></a>
            </div>
            <!-- Post -->
            <div class="typo" style="padding: 3rem;">
                <h2 id="一、Go-logger"><a href="#一、Go-logger" class="headerlink" title="一、Go  logger"></a>一、Go  logger</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span> Go loger</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">    优势</span></span><br><span class="line"><span class="comment">        它最大的优点是使用非常简单。我们可以设置任何io.Writer作为日志记录输出并向其发送要写入的日志。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    劣势</span></span><br><span class="line"><span class="comment">        仅限基本的日志级别</span></span><br><span class="line"><span class="comment">        只有一个Print选项。不支持INFO/DEBUG等多个级别。</span></span><br><span class="line"><span class="comment">        对于错误日志，它有Fatal和Panic</span></span><br><span class="line"><span class="comment">        Fatal日志通过调用os.Exit(1)来结束程序</span></span><br><span class="line"><span class="comment">        Panic日志在写入日志消息之后抛出一个panic</span></span><br><span class="line"><span class="comment">        但是它缺少一个ERROR日志级别，这个级别可以在不抛出panic或退出程序的情况下记录错误</span></span><br><span class="line"><span class="comment">        缺乏日志格式化的能力——例如记录调用者的函数名和行号，格式化日期和时间格式。等等。</span></span><br><span class="line"><span class="comment">        不提供日志切割的能力。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="number">2.</span></span><br></pre></td></tr></table></figure>

<h2 id="二、Uber-go-Zap"><a href="#二、Uber-go-Zap" class="headerlink" title="二、Uber-go Zap"></a>二、Uber-go Zap</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">Zap是非常快的、结构化的，分日志级别的Go日志库。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">它同时提供了结构化日志记录和printf风格的日志记录   非常的快</span></span><br><span class="line"><span class="comment">根据Uber-go Zap的文档，它的性能比类似的结构化日志包更好,同时也比标准库更快</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="number">1.</span> 安装</span><br><span class="line">	<span class="keyword">go</span> get -u <span class="keyword">go</span>.uber.org/zap</span><br><span class="line"></span><br><span class="line"><span class="number">2.</span> 配置Zap Logger</span><br><span class="line">    <span class="comment">// Zap提供了两种类型的日志记录器—Sugared Logger和Logger。</span></span><br><span class="line">    <span class="comment">// 在性能很好但不是很关键的上下文中，使用SugaredLogger。它比其他结构化日志记录包快4-10倍，并且支持结构化和printf风格的日志记录。</span></span><br><span class="line">    <span class="comment">// 在每一微秒和每一次内存分配都很重要的上下文中，使用Logger。它甚至比SugaredLogger更快，内存分配次数也更少，但它只支持强类型的结构化日志记录。</span></span><br></pre></td></tr></table></figure>

<h2 id="三、logger"><a href="#三、logger" class="headerlink" title="三、logger"></a>三、logger</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span> 文字简介</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">	通过调用zap.NewProduction() or zap.NewDevelopment() or zap.Example()创建一个Logger。</span></span><br><span class="line"><span class="comment">	上面的每一个函数都将创建一个logger。唯一的区别在于它将记录的信息不同。例如production logger默认记录调用函数信息、日期和时间等。</span></span><br><span class="line"><span class="comment">	通过Logger调用Info/Error等。</span></span><br><span class="line"><span class="comment">	默认情况下日志都会打印到应用程序的console界面。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="number">2</span> 代码演示</span><br><span class="line">    <span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line">	<span class="keyword">import</span> (</span><br><span class="line">		<span class="string">&quot;net/http&quot;</span></span><br><span class="line">		<span class="string">&quot;go.uber.org/zap&quot;</span></span><br><span class="line">    )</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> logger *zap.Logger</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">InitLogger</span><span class="params">()</span></span> &#123;</span><br><span class="line">        logger, _ = zap.NewProduction()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">simpleHttpGet</span><span class="params">(url <span class="keyword">string</span>)</span></span> &#123;</span><br><span class="line">        resp, err := http.Get(url)</span><br><span class="line">        <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">            logger.Error(</span><br><span class="line">                <span class="string">&quot;Error fetching url..&quot;</span>,</span><br><span class="line">                zap.String(<span class="string">&quot;url&quot;</span>, url),</span><br><span class="line">                zap.Error(err))</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            logger.Info(<span class="string">&quot;Success..&quot;</span>,</span><br><span class="line">                zap.String(<span class="string">&quot;statusCode&quot;</span>, resp.Status),</span><br><span class="line">                zap.String(<span class="string">&quot;url&quot;</span>, url))</span><br><span class="line">            resp.Body.Close()</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        InitLogger()</span><br><span class="line">        <span class="keyword">defer</span> logger.Sync()</span><br><span class="line">        simpleHttpGet(<span class="string">&quot;www.baidu.com&quot;</span>)</span><br><span class="line">        simpleHttpGet(<span class="string">&quot;http://www.mzitu.com&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="四、Sugared-Logger"><a href="#四、Sugared-Logger" class="headerlink" title="四、Sugared Logger"></a>四、Sugared Logger</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">现在让我们使用Sugared Logger来实现相同的功能。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">大部分的实现基本都相同。</span></span><br><span class="line"><span class="comment">惟一的区别是，我们通过调用主logger的. Sugar()方法来获取一个SugaredLogger。</span></span><br><span class="line"><span class="comment">然后使用SugaredLogger以printf格式记录语句</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="number">1.</span> 代码演示</span><br><span class="line">    <span class="keyword">var</span> sugarLogger *zap.SugaredLogger</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        InitLogger()</span><br><span class="line">        <span class="keyword">defer</span> sugarLogger.Sync()</span><br><span class="line">        simpleHttpGet(<span class="string">&quot;www.google.com&quot;</span>)</span><br><span class="line">        simpleHttpGet(<span class="string">&quot;http://www.google.com&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">InitLogger</span><span class="params">()</span></span> &#123;</span><br><span class="line">      logger, _ := zap.NewProduction()</span><br><span class="line">        sugarLogger = logger.Sugar()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">simpleHttpGet</span><span class="params">(url <span class="keyword">string</span>)</span></span> &#123;</span><br><span class="line">        sugarLogger.Debugf(<span class="string">&quot;Trying to hit GET request for %s&quot;</span>, url)</span><br><span class="line">        resp, err := http.Get(url)</span><br><span class="line">        <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">            sugarLogger.Errorf(<span class="string">&quot;Error fetching URL %s : Error = %s&quot;</span>, url, err)</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            sugarLogger.Infof(<span class="string">&quot;Success! statusCode = %s for URL %s&quot;</span>, resp.Status, url)</span><br><span class="line">            resp.Body.Close()</span><br><span class="line">        &#125;</span><br><span class="line">            </span><br><span class="line"><span class="comment">// 到目前为止这两个logger都打印输出JSON结构格式。</span></span><br></pre></td></tr></table></figure>

<h2 id="五、使用Lumberjack进行日志切割归档"><a href="#五、使用Lumberjack进行日志切割归档" class="headerlink" title="五、使用Lumberjack进行日志切割归档"></a>五、使用Lumberjack进行日志切割归档</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line">这个日志程序中唯一缺少的就是日志切割归档功能。</span><br><span class="line"></span><br><span class="line">Zap本身不支持切割归档日志文件</span><br><span class="line"></span><br><span class="line">为了添加日志切割归档功能，我们将使用第三方库Lumberjack来实现。</span><br><span class="line"></span><br><span class="line">安装</span><br><span class="line">执行下面的命令安装Lumberjack</span><br><span class="line"></span><br><span class="line"><span class="keyword">go</span> get -u github.com/natefinch/lumberjack</span><br><span class="line"></span><br><span class="line"><span class="number">1.</span> 代码演示</span><br><span class="line">	要在zap中加入Lumberjack支持，我们需要修改WriteSyncer代码。我们将按照下面的代码修改getLogWriter()函数：</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">getLogWriter</span><span class="params">()</span> <span class="title">zapcore</span>.<span class="title">WriteSyncer</span></span> &#123;</span><br><span class="line">        lumberJackLogger := &amp;lumberjack.Logger&#123;</span><br><span class="line">            Filename:   <span class="string">&quot;./test.log&quot;</span>, <span class="comment">// 日志文件的位置</span></span><br><span class="line">            MaxSize:    <span class="number">10</span>, <span class="comment">// 在进行切割之前，日志文件的最大大小(以MB为单位)</span></span><br><span class="line">            MaxBackups: <span class="number">5</span>, <span class="comment">// 保留旧文件的最大个数</span></span><br><span class="line">            MaxAge:     <span class="number">30</span>, <span class="comment">// 保留旧文件的最大天数</span></span><br><span class="line">            Compress:   <span class="literal">false</span>, <span class="comment">// 是否压缩/归档旧文件</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> zapcore.AddSync(lumberJackLogger)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="number">2.</span> 完整代码</span><br><span class="line">    <span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line">    <span class="keyword">import</span> (</span><br><span class="line">        <span class="string">&quot;net/http&quot;</span></span><br><span class="line"></span><br><span class="line">        <span class="string">&quot;github.com/natefinch/lumberjack&quot;</span></span><br><span class="line">        <span class="string">&quot;go.uber.org/zap&quot;</span></span><br><span class="line">        <span class="string">&quot;go.uber.org/zap/zapcore&quot;</span></span><br><span class="line">    )</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> sugarLogger *zap.SugaredLogger</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        InitLogger()</span><br><span class="line">        <span class="keyword">defer</span> sugarLogger.Sync()</span><br><span class="line">        simpleHttpGet(<span class="string">&quot;www.sogo.com&quot;</span>)</span><br><span class="line">        simpleHttpGet(<span class="string">&quot;http://www.sogo.com&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">InitLogger</span><span class="params">()</span></span> &#123;</span><br><span class="line">        writeSyncer := getLogWriter()</span><br><span class="line">        encoder := getEncoder()</span><br><span class="line">        core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)</span><br><span class="line"></span><br><span class="line">        logger := zap.New(core, zap.AddCaller())</span><br><span class="line">        sugarLogger = logger.Sugar()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">getEncoder</span><span class="params">()</span> <span class="title">zapcore</span>.<span class="title">Encoder</span></span> &#123;</span><br><span class="line">        encoderConfig := zap.NewProductionEncoderConfig()</span><br><span class="line">        encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder</span><br><span class="line">        encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder</span><br><span class="line">        <span class="keyword">return</span> zapcore.NewConsoleEncoder(encoderConfig)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">getLogWriter</span><span class="params">()</span> <span class="title">zapcore</span>.<span class="title">WriteSyncer</span></span> &#123;</span><br><span class="line">        lumberJackLogger := &amp;lumberjack.Logger&#123;</span><br><span class="line">            Filename:   <span class="string">&quot;./test.log&quot;</span>,</span><br><span class="line">            MaxSize:    <span class="number">1</span>,</span><br><span class="line">            MaxBackups: <span class="number">5</span>,</span><br><span class="line">            MaxAge:     <span class="number">30</span>,</span><br><span class="line">            Compress:   <span class="literal">false</span>,</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> zapcore.AddSync(lumberJackLogger)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">simpleHttpGet</span><span class="params">(url <span class="keyword">string</span>)</span></span> &#123;</span><br><span class="line">        sugarLogger.Debugf(<span class="string">&quot;Trying to hit GET request for %s&quot;</span>, url)</span><br><span class="line">        resp, err := http.Get(url)</span><br><span class="line">        <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">            sugarLogger.Errorf(<span class="string">&quot;Error fetching URL %s : Error = %s&quot;</span>, url, err)</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            sugarLogger.Infof(<span class="string">&quot;Success! statusCode = %s for URL %s&quot;</span>, resp.Status, url)</span><br><span class="line">            resp.Body.Close()</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h2 id="六、如何在gin框架中使用zap日志库"><a href="#六、如何在gin框架中使用zap日志库" class="headerlink" title="六、如何在gin框架中使用zap日志库"></a>六、如何在gin框架中使用zap日志库</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span> gin</span><br><span class="line">    我们在使用gin.Default()的时候，Default就帮我们使用两个中间件了(Logger()  Recovery())</span><br><span class="line">    其中Logger()是把gin框架本身的日志输出到标准输出（我们本地开发调试时在终端输出的那些日志就是它的功劳）</span><br><span class="line">    而Recovery()是在程序出现<span class="built_in">panic</span>的时候恢复现场并写入<span class="number">500</span>响应的。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    所以我们想在gin框架中使用zap日志库，我们就得使用gin.New()方法，并且重写这两个中间件</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="number">2.</span> 代码演示</span><br><span class="line">    <span class="comment">// GinLogger 接收gin框架默认的日志</span></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">GinLogger</span><span class="params">(logger *zap.Logger)</span> <span class="title">gin</span>.<span class="title">HandlerFunc</span></span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            start := time.Now()</span><br><span class="line">            path := c.Request.URL.Path</span><br><span class="line">            query := c.Request.URL.RawQuery</span><br><span class="line">            c.Next()</span><br><span class="line"></span><br><span class="line">            cost := time.Since(start)</span><br><span class="line">            logger.Info(path,</span><br><span class="line">                zap.Int(<span class="string">&quot;status&quot;</span>, c.Writer.Status()),</span><br><span class="line">                zap.String(<span class="string">&quot;method&quot;</span>, c.Request.Method),</span><br><span class="line">                zap.String(<span class="string">&quot;path&quot;</span>, path),</span><br><span class="line">                zap.String(<span class="string">&quot;query&quot;</span>, query),</span><br><span class="line">                zap.String(<span class="string">&quot;ip&quot;</span>, c.ClientIP()),</span><br><span class="line">                zap.String(<span class="string">&quot;user-agent&quot;</span>, c.Request.UserAgent()),</span><br><span class="line">                zap.String(<span class="string">&quot;errors&quot;</span>, c.Errors.ByType(gin.ErrorTypePrivate).String()),</span><br><span class="line">                zap.Duration(<span class="string">&quot;cost&quot;</span>, cost),</span><br><span class="line">            )</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// GinRecovery recover掉项目可能出现的panic</span></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">GinRecovery</span><span class="params">(logger *zap.Logger, stack <span class="keyword">bool</span>)</span> <span class="title">gin</span>.<span class="title">HandlerFunc</span></span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            <span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">                <span class="keyword">if</span> err := <span class="built_in">recover</span>(); err != <span class="literal">nil</span> &#123;</span><br><span class="line">                    <span class="comment">// Check for a broken connection, as it is not really a</span></span><br><span class="line">                    <span class="comment">// condition that warrants a panic stack trace.</span></span><br><span class="line">                    <span class="keyword">var</span> brokenPipe <span class="keyword">bool</span></span><br><span class="line">                    <span class="keyword">if</span> ne, ok := err.(*net.OpError); ok &#123;</span><br><span class="line">                        <span class="keyword">if</span> se, ok := ne.Err.(*os.SyscallError); ok &#123;</span><br><span class="line">                            <span class="keyword">if</span> strings.Contains(strings.ToLower(se.Error()), <span class="string">&quot;broken pipe&quot;</span>) || strings.Contains(strings.ToLower(se.Error()), <span class="string">&quot;connection reset by peer&quot;</span>) &#123;</span><br><span class="line">                                brokenPipe = <span class="literal">true</span></span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line"></span><br><span class="line">                    httpRequest, _ := httputil.DumpRequest(c.Request, <span class="literal">false</span>)</span><br><span class="line">                    <span class="keyword">if</span> brokenPipe &#123;</span><br><span class="line">                        logger.Error(c.Request.URL.Path,</span><br><span class="line">                            zap.Any(<span class="string">&quot;error&quot;</span>, err),</span><br><span class="line">                            zap.String(<span class="string">&quot;request&quot;</span>, <span class="keyword">string</span>(httpRequest)),</span><br><span class="line">                        )</span><br><span class="line">                        <span class="comment">// If the connection is dead, we can&#x27;t write a status to it.</span></span><br><span class="line">                        c.Error(err.(error)) <span class="comment">// nolint: errcheck</span></span><br><span class="line">                        c.Abort()</span><br><span class="line">                        <span class="keyword">return</span></span><br><span class="line">                    &#125;</span><br><span class="line"></span><br><span class="line">                    <span class="keyword">if</span> stack &#123;</span><br><span class="line">                        logger.Error(<span class="string">&quot;[Recovery from panic]&quot;</span>,</span><br><span class="line">                            zap.Any(<span class="string">&quot;error&quot;</span>, err),</span><br><span class="line">                            zap.String(<span class="string">&quot;request&quot;</span>, <span class="keyword">string</span>(httpRequest)),</span><br><span class="line">                            zap.String(<span class="string">&quot;stack&quot;</span>, <span class="keyword">string</span>(debug.Stack())),</span><br><span class="line">                        )</span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        logger.Error(<span class="string">&quot;[Recovery from panic]&quot;</span>,</span><br><span class="line">                            zap.Any(<span class="string">&quot;error&quot;</span>, err),</span><br><span class="line">                            zap.String(<span class="string">&quot;request&quot;</span>, <span class="keyword">string</span>(httpRequest)),</span><br><span class="line">                        )</span><br><span class="line">                    &#125;</span><br><span class="line">                    c.AbortWithStatus(http.StatusInternalServerError)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;()</span><br><span class="line">            c.Next()</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 如果不想自己实现，可以使用github上有别人封装好的https://github.com/gin-contrib/zap。</span></span><br><span class="line"><span class="comment">// 这样我们就可以在gin框架中使用我们上面定义好的两个中间件来代替gin框架默认的Logger()和Recovery()了。</span></span><br><span class="line">    r := gin.New()</span><br><span class="line">    r.Use(GinLogger(), GinRecovery())</span><br></pre></td></tr></table></figure>


            </div>

            <!-- Post Comments -->
            
    <!-- 使用 DISQUS_CLICK -->
<div id="disqus-comment">
    <div id="disqus_thread"></div>

<!-- add animation -->
<style>
	.disqus_click_btn {
            line-height: 30px;
            margin: 0;
            min-width: 50px;
            padding: 0 14px;
            display: inline-block;
            font-family: "Roboto", "Helvetica", "Arial", sans-serif;
            font-size: 14px;
            font-weight: 400;
            text-transform: uppercase;
            letter-spacing: 0;
            overflow: hidden;
            will-change: box-shadow;
            transition: box-shadow .2s cubic-bezier(.4, 0, 1, 1), background-color .2s cubic-bezier(.4, 0, .2, 1), color .2s cubic-bezier(.4, 0, .2, 1);
            outline: 0;
            cursor: pointer;
            text-decoration: none;
            text-align: center;
            vertical-align: middle;
            border: 0;
            background: rgba(158, 158, 158, .2);
            box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
            color: #fff;
            background-color: #7EC0EE;
            text-shadow: 0
        }
</style>
	
<div class="btn_click_load" id="disqus_bt"> 
    <button class="disqus_click_btn">点击查看评论</button>
</div>

<!--
<script type="text/javascript">
$('.btn_click_load').click(function() {
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'http-miccall-tech'; // required: replace example with your forum shortname

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
      var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
      dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();

    document.getElementById('disqus_bt').style.display = "none";
});
</script>
-->
<script type="text/javascript">
    var disqus_config = function () {
        this.page.url = 'https://gitee.com/AmeX/amelin-ting.git/2018/05/23/Go%E6%97%A5%E5%BF%97%E5%BA%93------Zap/';  // Replace PAGE_URL with your page's canonical URL variable
        this.page.identifier = 'https://gitee.com/AmeX/amelin-ting.git/2018/05/23/Go%E6%97%A5%E5%BF%97%E5%BA%93------Zap/'; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
    };
</script>

<script type="text/javascript">
    $('.btn_click_load').click(function() {  //click to load comments
        (function() { // DON'T EDIT BELOW THIS LINE
            var d = document;
            var s = d.createElement('script');
            s.src = '//http-miccall-tech.disqus.com/embed.js';
            s.setAttribute('data-timestamp', + new Date());
            (d.head || d.body).appendChild(s);
        })();
        $('.btn_click_load').css('display','none');
    });
</script>
</div>
<style>
    #disqus-comment{
        background-color: #eee;
        padding: 2pc;
    }
</style>


        </div>
        <!-- Copyright 版权 start -->
                <div id="copyright">
            <ul>
                <li>&copy;Powered By <a target="_blank" rel="noopener" href="https://hexo.io/zh-cn/" style="border-bottom: none;">hexo</a></li>
                <li>Design: <a target="_blank" rel="noopener" href="http://miccall.tech " style="border-bottom: none;">miccall</a></li>
            </ul>
            
                <span id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span>次</span>
			
        </div>
    </div>
</body>



 	
</html>
